//
//  LYCollectionViewLayout.m
//  MyProject
//
//  Created by yun on 2018/7/9.
//  Copyright © 2018年 yun. All rights reserved.
//

#import "LYCollectionViewLayout.h"

static NSInteger const LY_Column = 3;// 默认列数
static CGFloat const LY_ColunmSpacing = 10;// 默认列间距
static CGFloat const LY_LineSpacing = 10;// 默认行间距
static UIEdgeInsets const LY_EdgeInsets = {10, 10, 10, 10};// 默认内边距

@interface LYCollectionViewLayout ()
// Attributes数组
@property(nonatomic,strong) NSMutableArray *attributesArray;
// 每列高度
@property(nonatomic,strong) NSMutableArray *columnHeightsArray;

@property(nonatomic,strong) NSIndexPath *ly_indexPath;


- (NSInteger)ly_colunmCount;
- (CGFloat)ly_columnSpacing;
- (CGFloat)ly_lineSpacing;
- (UIEdgeInsets)ly_edgeInsets;

@end

@implementation LYCollectionViewLayout

/**
 * UICollectionViewLayout和UICollectionViewFlowLayout
 UICollectionViewFlowLayout是UICollectionViewLayout子类，一般用UICollectionViewFlowLayout进行瀑布流布局
 这里我们采用继承UICollectionViewLayout的方式进行布局
 
 自定义继承自UICollectionViewLayout的子类来进行实现布局
 调用- (void)prepareLayout进行初始化
 重载- (CGSize)collectionViewContentSize返回内容的大小
 重载- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect方法返回rect中所有元素的布局属性，返回的是一个数组
 重载- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath方法返回对应的indexPath的位置的cell的布局属性。
 重载- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath;方法返回对应indexPath的位置的追加视图的布局属性，如果没有就不用重载
 重载- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString*)elementKind atIndexPath:(NSIndexPath *)indexPath;方法返回对应indexPath的位置的装饰视图的布局属性，如果没有也不需要重载
 重载- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;当边界发生改变时，是否应该刷新。
 
 */

// 告诉布局对象更新当前布局。
- (void)prepareLayout{
    [super prepareLayout];
    // 删除之前所有高度
    [self.columnHeightsArray removeAllObjects];
    
    for (int i = 0; i < self.ly_colunmCount; i++) {// 默认列高度
        [self.columnHeightsArray addObject:@(self.ly_edgeInsets.top)];
    }
    // 删除之前所有attributes
    [self.attributesArray removeAllObjects];
    
    // 分成section和item
    NSInteger sections = self.collectionView.numberOfSections;
    for (int s = 0; s < sections; s++) {
        for (int i = 0; i < [self.collectionView numberOfItemsInSection:s]; i++ ) {
            [self.attributesArray addObject:[self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:s]]];
        }
    }
    
    
}
// 布局属性
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
    
    UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    
    CGFloat itemWidth = floorf((CGRectGetWidth(self.collectionView.frame) - self.ly_edgeInsets.left - self.ly_edgeInsets.right - self.ly_columnSpacing * (self.ly_colunmCount - 1)) * 1.f / self.ly_colunmCount);
    // floorf:如果参数是小数，则求最大的整数但不大于本身.
    CGFloat itemHeight = [self.delegate ly_collectionView:self.collectionView layout:self heightForItemAtIndexPath:indexPath itemWidth:itemWidth];
    
    // 找出最短的一列
    NSInteger indexCol = 0;
    CGFloat minColH = [self.columnHeightsArray[indexCol] floatValue];
    for (int i = 1; i < self.columnHeightsArray.count; i++) {
        CGFloat colH = [self.columnHeightsArray[i] floatValue];
        if (minColH > colH) {
            minColH = colH;
            indexCol = i;
        }
    }
    
    // 下一个布局item x,y值
    CGFloat x = self.ly_edgeInsets.left + (self.ly_columnSpacing + itemWidth) * indexCol;
    CGFloat y = minColH + self.ly_lineSpacing;
    // 是不是第一行
    if (minColH == self.ly_edgeInsets.top) {
        y = self.ly_edgeInsets.top;
    }
    
    attrs.frame = CGRectMake(x, y, itemWidth, itemHeight);
    self.columnHeightsArray[indexCol] = @(CGRectGetMaxY(attrs.frame));// 
    return attrs;
}

/**
 * 返回指定矩形中所有单元格和视图的布局属性。
 */
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
    
    return self.attributesArray;
}

/**
 * 内容的大小,最长列
 */
- (CGSize)collectionViewContentSize{
    
    CGFloat maxColH = [self.columnHeightsArray.firstObject floatValue];
    
    for (NSInteger i = 1; i < self.columnHeightsArray.count; i++){
        CGFloat colH = [self.columnHeightsArray[i] floatValue];
        if(maxColH < colH){
            maxColH = colH;
        }
    }
    
    return CGSizeMake(self.collectionView.frame.size.width, maxColH + self.ly_edgeInsets.bottom);
}

#pragma mark -- method

- (NSInteger)ly_colunmCount{
    if (self.delegate && [self.delegate respondsToSelector:@selector(ly_collectionView:layout:columnForSectionAtIndex:)]) {
        return [self.delegate ly_collectionView:self.collectionView layout:self columnForSectionAtIndex:self.ly_indexPath.section];
    } else {
        return LY_Column;
    }
}

- (CGFloat)ly_columnSpacing{
    if (self.delegate && [self.delegate respondsToSelector:@selector(ly_collectionView:layout:columnSpacingForSectionAtIndex:)]) {
        return [self.delegate ly_collectionView:self.collectionView layout:self columnSpacingForSectionAtIndex:self.ly_indexPath.section];
    } else {
        return LY_ColunmSpacing;
    }
}

- (CGFloat)ly_lineSpacing{
    if (self.delegate && [self.delegate respondsToSelector:@selector(ly_collectionView:layout:lineSpacingForSectionAtIndex:)]) {
        return [self.delegate ly_collectionView:self.collectionView layout:self lineSpacingForSectionAtIndex:self.ly_indexPath.section];
    } else {
        return LY_LineSpacing;
    }
}
- (UIEdgeInsets)ly_edgeInsets{
    if (self.delegate && [self.delegate respondsToSelector:@selector(ly_collectionView:layout:edgeInsetForSectionAtIndex:)]) {
        return [self.delegate ly_collectionView:self.collectionView layout:self edgeInsetForSectionAtIndex:self.ly_indexPath.section];
    } else {
        return LY_EdgeInsets;
    }
}


#pragma mark -- 懒加载

- (NSMutableArray *)attributesArray{
    if (!_attributesArray) {
        _attributesArray = [NSMutableArray new];
    }
    return _attributesArray;
}
- (NSMutableArray *)columnHeightsArray{
    if (!_columnHeightsArray) {
        _columnHeightsArray = [NSMutableArray new];
    }
    return _columnHeightsArray;
}

- (NSIndexPath *)ly_indexPath{
    if (!_ly_indexPath) {
        _ly_indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
    }
    return _ly_indexPath;
}


@end
